﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MyCommunity.Models;
using System.Web.Security;
using MyCommunity.BusinessLogic;

namespace MyCommunity.Controllers
{
    public class UserController : Controller
    {

        private readonly IUserService _userService;
        private readonly IUserEventAttendanceService _userEventAttendanceService;

        public UserController(IUserService userService, IUserEventAttendanceService userEventAttendanceService)
        {
            _userService = userService;
            _userEventAttendanceService = userEventAttendanceService;       
        }

        [Authorize]
        public ActionResult Index(String searchString)
        {
            var viewModel = new SearchViewModel<UserViewModel>
            {
                users = _userService.FindUsers(searchString),
                search = searchString,
            };
            return View(viewModel);
        }

        [Authorize]      
        public ActionResult AutoComplete(string term)
        {
            if (!string.IsNullOrEmpty(term) && term.Length > 2)
            {
                var results = _userService.FindUsers(term)
                .Select(i => new { label = i.Firstname + " " + i.Lastname, id = i.Id });
                return Json(results.ToArray(),
                JsonRequestBehavior.AllowGet);
            }
            else
            {
                return Json(null, JsonRequestBehavior.AllowGet);
            }
        }


        public ActionResult Register()
        {
            return View();
        }

        [HttpPost]
        public ActionResult Register(UserRegisterModel userRegisterModel)
        {
            if (ModelState.IsValid)
            {

                User user = _userService.CreateUser(userRegisterModel);

                if (user != null)
                {
                    _userService.SaveChanges();

                    return RedirectToAction("Activate", "User", _userService.getUser(user.Mail, user.Password));
                }
                else
                {
                    ModelState.AddModelError("Mail", "Mail Address is already in use");
                }
            }

            // If we got this far, something failed, redisplay form
            return View(userRegisterModel);
        }

        public ActionResult PasswordForgotten()
        {
            return View();
        }

        [HttpPost]
        public ActionResult PasswordForgotten(PasswordForgottenModel model)
        {
            User user = _userService.getUser(model.Mail);

            if (user != null)
            {
                string pw = UserService.GeneratePW(6);
                user.Password = UserService.MD5Hash(pw);
                _userService.SaveChanges();

                ModelState.AddModelError("", "Password was changed to: " + pw);
            }
            else
            {
                ModelState.AddModelError("Mail", "Mail Address is not in the system");
            }

            return View(model);
        }

        public ActionResult Activate(User user)
        {
            String guid = System.Guid.NewGuid().ToString();
            CacheController.addGUID(user, guid);

            return View(new UserActivateModel(user, guid));
        }

        [HttpGet]
        public ActionResult ActivateUser(String mail, String guid)
        {
            String guidCache = CacheController.getGUID(mail);

            if(guidCache.Equals(guid)) {

                User user = _userService.getUser(mail);

                if (user != null)
                {
                    user.IsActive = true;
                    _userService.SaveChanges();

                    CacheController.removeGUID(mail);

                    return RedirectToAction("LogIn", "User", new { id = user.Id });
                }

            }

            return RedirectToAction("Index", "Home");
        }

        public ActionResult LogIn()
        {
            return View();
        }

        [HttpPost]
        public ActionResult LogIn(UserLoginModel model, string returnUrl)
        {
            if (ModelState.IsValid)
            {
                User user = _userService.getUser(model.Mail, UserService.MD5Hash(model.Password));

                if (user != null)
                {

                    if (user.IsActive)
                    {

                        FormsAuthentication.SetAuthCookie(model.Mail, model.RememberMe);
                        if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/")
                            && !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\"))
                        {
                            return Redirect(returnUrl);
                        }
                        else
                        {
                            return RedirectToAction("Details", "User", new { id = user.Id });
                        }
                    }
                    else
                    {
                        ModelState.AddModelError("", "The user is not active now.");
                    }
                }
                else
                {
                    ModelState.AddModelError("", "The user name or password provided is incorrect.");
                }
            }

            // If we got this far, something failed, redisplay form
            return View(model);
        }

        [Authorize]
        public ActionResult LogOff()
        {
            FormsAuthentication.SignOut();

            return RedirectToAction("Index", "Home");
        }

        [Authorize]
        public ActionResult Details(int id)
        {
            UserViewModel model = new UserViewModel(_userService.GetUser(id));
            model.SetAttendance(_userEventAttendanceService.GetAllUserEvents(id));

            String userMail = User.Identity.Name;
            User user = _userService.getUser(userMail);

            model.isLoggedInAdmin = user.IsAdmin;
            model.loggedInUserId = user.Id;

            return View(model);
        }


        public ActionResult UserDetails()
        {
            String userMail = User.Identity.Name;
            if (userMail == "")
            {
                return RedirectToAction("LogIn", "User");
            }
            else
            {
                User user = _userService.getUser(userMail);
                return RedirectToAction("Details", "User", new { id = user.Id });
            }
        }

        [Authorize]
        public ActionResult Edit(int id)
        {
            String userMail = User.Identity.Name;
            User user = _userService.getUser(userMail);

            if (user.Id == id || user.IsAdmin)
            {

                UserViewModel model = new UserViewModel(_userService.GetUser(id));
                model.isLoggedInAdmin = user.IsAdmin;
                model.loggedInUserId = user.Id;

                return View(model);

            }

            return RedirectToAction("Details", "User", new { id = id });
        }


        [Authorize]
        [HttpPost]
        public ActionResult Edit(UserViewModel model)
        {

            User user = _userService.GetUser(model.Id);

            try
            {

                model.ApplyChanges(user);
                _userService.SaveChanges();

                return RedirectToAction("Details", "User", new { id = model.Id });
            }
            catch
            {
                return View(new UserViewModel(user));
            }
        }

        [Authorize]
        public ActionResult ChangePassword(int id)
        {
            return View(new ChangePasswordModel(id));
        }

        [Authorize]
        [HttpPost]
        public ActionResult ChangePassword(ChangePasswordModel model)
        {
            if (ModelState.IsValid)
            {

                var mail = HttpContext.User.Identity.Name;

                User user = _userService.getUser(mail, UserService.MD5Hash(model.OldPassword));

                if (user != null)
                {
                    user.Password = UserService.MD5Hash(model.NewPassword);
                    _userService.SaveChanges();
                    model.id = user.Id;

                    ModelState.AddModelError("", "Password was changed");
                } 
                else
                {
                    ModelState.AddModelError("OldPassword", "Password is incorrect");
                }
            }


            return View(model);
        }


        [Authorize(Roles = RolesUtil.Admin)]
        public ActionResult Delete(int id)
        {
            return View();
        }

        [Authorize(Roles = RolesUtil.Admin)]
        public ActionResult Delete(int id, FormCollection collection)
        {
            try
            {
                // TODO: Add delete logic here
 
                return RedirectToAction("Index");
            }
            catch
            {
                return View();
            }
        }
     

    }
}
